/*
 *MIT License
 *
 *Copyright (c) 2019 chenshuai cs4380@163.com
 *
 *Permission is hereby granted, free of charge, to any person obtaining a copy
 *of this software and associated documentation files (the "Software"), to deal
 *in the Software without restriction, including without limitation the rights
 *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *copies of the Software, and to permit persons to whom the Software is
 *furnished to do so, subject to the following conditions:
 *
 *The above copyright notice and this permission notice shall be included in all
 *copies or substantial portions of the Software.
 *
 *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 *SOFTWARE.
 */

package com.cs.cslc.admin.biz;

import com.cs.cslc.admin.dto.RoleMenuAuthDTO;
import com.cs.cslc.admin.mapper.SysRoleAuthorizationMapper;
import com.cs.cslc.admin.pojo.SysRoleAuthorization;
import com.cs.cslc.admin.vo.RoleAuthorizationVO;
import com.cs.cslc.common.biz.BaseBusinessBiz;
import com.cs.cslc.common.util.BeanUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * SysRoleAuthorization 系统角色授权关系表.
 *
 * @author cs
 * @version 1.0
 * @date 2019-11-13 10:43
 * @description
 */
@Service
public class SysRoleAuthorizationBiz extends BaseBusinessBiz<SysRoleAuthorizationMapper, SysRoleAuthorization> {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SysMenuButtonBiz menuButtonBiz;

    /**
     * 添加指定角色的菜单权限
     *
     * @param roleCode    角色编码
     * @param roleMenusVO 角色菜单关系
     */
    @Transactional(rollbackFor = {Exception.class, RuntimeException.class})
    public void setRoleAuth(String roleCode, RoleAuthorizationVO roleMenusVO) {
        Integer resourceType = roleMenusVO.getResourceType();
        List<String> resourceIds = roleMenusVO.getResourceIds();
        String menuCode = roleMenusVO.getMenuCode();
        // 删除指定角色的的菜单权限
        this.delByRoleCode(roleCode, resourceType, roleMenusVO.getMenuCode());
        // List<Integer> buttonIds = new ArrayList<>();
        // 添加指定角色的菜单权限
        SysRoleAuthorization roleAuth;
        for (String resourceId : resourceIds) {
            roleAuth = new SysRoleAuthorization();
            roleAuth.setRoleCode(roleCode);
            roleAuth.setResourceId(resourceId);
            roleAuth.setResourceType(resourceType);
            roleAuth.setMenuCode(menuCode);
            this.baseMapper.insertSelective(roleAuth);
            // 聚合菜单按钮ids
//            if (SysRoleAuthorization.BUTTON_RESOURCE_TYPE.equals(resourceType)) {
//                buttonIds.add(Integer.valueOf(resourceId));
//            }
        }
//        // 缓存角色菜单权限到redis中
//        if (SysRoleAuthorization.BUTTON_RESOURCE_TYPE.equals(resourceType)) {
//            List<SysMenuButton> menuButtonList = menuButtonBiz.getMenuButtonByIds(buttonIds);
//            redisTemplate.opsForHash().put(RedisKeysConstant.ROLES_BUTTON_AUTH_KEY, roleCode, menuButtonList);
//        }
    }

    /**
     * 删除指定角色的权限
     * <p>
     * 可指定资源类型
     * </p>
     *
     * @param roleCode     角色编码
     * @param resourceType 资源类型
     * @param menuCode     菜单按钮对应的菜单编码
     */
    public int delByRoleCode(String roleCode, Integer resourceType, String menuCode) {
        if (StringUtils.isBlank(roleCode)) {
            return 0;
        }
        SysRoleAuthorization roleAuth = new SysRoleAuthorization();
        roleAuth.setRoleCode(roleCode);
        roleAuth.setMenuCode(menuCode);
        if (null != resourceType) {
            roleAuth.setResourceType(resourceType);
        }
        return this.baseMapper.delete(roleAuth);
    }

    /**
     * 获取指定角色的菜单或者按钮权限
     *
     * @param roleCode     角色编码
     * @param resourceType 权限类型
     * @return 权限ids
     */
    public List<String> getAuthIdByRoleCode(String roleCode, Integer resourceType) {
        List<SysRoleAuthorization> roleAuthList = this.getAuthByRoleCode(roleCode, resourceType);
        List<String> resourceIds = roleAuthList.stream().map(SysRoleAuthorization::getResourceId).collect(Collectors.toList());
        return resourceIds;
    }

    /**
     * 获取指定角色权限
     *
     * @param roleCode     角色编码
     * @param resourceType 资源类型
     * @return
     */
    public List<SysRoleAuthorization> getAuthByRoleCode(String roleCode, Integer resourceType) {
        if (StringUtils.isBlank(roleCode)) {
            return new ArrayList<>();
        }
        SysRoleAuthorization roleAuth = new SysRoleAuthorization();
        roleAuth.setRoleCode(roleCode);
        if (null != resourceType) {
            roleAuth.setResourceType(resourceType);
        }
        return this.baseMapper.select(roleAuth);
    }

    /**
     * 通过角色编码获取角色权限
     *
     * @param roleCodeList 角色编码集合
     * @return
     */
    public List<SysRoleAuthorization> getRoleAuthByRoleCodes(List<String> roleCodeList) {
        if (BeanUtil.isEmpty(roleCodeList)) {
            return new ArrayList<>();
        }
        return this.baseMapper.selectRoleAuthByRoleCodes(roleCodeList);
    }

    /**
     * 获取角色对应的菜单权限集合
     *
     * @param roleCode 角色编码
     * @return
     */
    public List<String> getMenuAuthByRoleCode(String roleCode) {
        return this.baseMapper.selectMenuAuthByRoleCode(roleCode);
    }

    /**
     * 初始化菜单角色
     * TODO 缓存到redis中
     */
    public Map<String, List<RoleMenuAuthDTO>> initRoleMenus() {
        Map<String, List<RoleMenuAuthDTO>> result = new HashMap<>();
        // 更新角色权限
        List<RoleMenuAuthDTO> roleMenuList = this.baseMapper.selectRoleMenus();
        if (BeanUtil.isNotEmpty(roleMenuList)) {
            List<RoleMenuAuthDTO> tmpeRoleMenuList;
            for (RoleMenuAuthDTO roleMenuAuthDTO : roleMenuList) {
                tmpeRoleMenuList = result.get(roleMenuAuthDTO.getRoleCode());
                if (BeanUtil.isEmpty(tmpeRoleMenuList)) {
                    tmpeRoleMenuList = new ArrayList<>();
                }
                tmpeRoleMenuList.add(roleMenuAuthDTO);
                result.put(roleMenuAuthDTO.getRoleCode(), tmpeRoleMenuList);
            }
        }
        return result;
    }
}